def is_prime(n: int) -> bool:
    """check whether an integer n is prime"""
    if n < 2: return False
    i = 2
    while i <= n // i:
        if n % i == 0: return False
        i += 1
    return True


from typing import List
def get_primes_until(n: int) -> List[int]:
    """get prime numbers between [1, n] by sieve of Euler, assuming n is integer"""
    if n < 2: return []
    primes = []
    vis = [False] * (n + 1)
    for i in range(2, n + 1):
        if not vis[i]: primes.append(i)
        for p in primes:
            if p > n // i: break
            vis[i * p] = True
            if i % p == 0: break
    return primes


from typing import List
from math import sqrt
def get_primes_between(a: int, b: int) -> List[int]:
    """get prime numbers between [a, b], assuming a, b are integers"""
    if a < 2: a = 2
    if a > b: return []
    primes_until_sqrt_b = get_primes_until(int(sqrt(b)))
    if len(primes_until_sqrt_b) == 0:
        # 2 <= a <= b <= 3
        return [a, b] if a != b else [a]
    # we get prime numbers between [a, c) from primes_until_sqrt_b 
    # and prime numbers between [c, b] by sieve of Eratosthenes
    c = max(a, primes_until_sqrt_b[-1] + 1)
    primes = []
    vis = [False] * (b - c + 1)
    for p in primes_until_sqrt_b:
        for j in range((c - 1) // p * p + p, b + 1, p):
            vis[j - c] = True
        if p >= a:
            # append prime numbers between [a, c)
            primes.append(p)
    # append prime numbers between [c, b]
    for i in range(c, b + 1):
        if not vis[i - c]: primes.append(i)
    return primes
